package cc.rengu.igas.channel.cpcn.core.service.base;

import cc.rengu.igas.channel.cpcn.facade.base.BaseRequest;
import cc.rengu.oltp.service.base.RadpService;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.enums.OltpRpcdEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.model.TxnInfo;
import cc.rengu.oltp.service.realize.ChannelService;
import cc.rengu.oltp.service.realize.impl.ChannelServiceImpl;
import cc.rengu.oltp.utility.util.ConvertUtil;
import cc.rengu.oltp.utility.util.RedisUtil;
import cc.rengu.oltp.utility.util.XmlTreeUtil;
import com.alibaba.fastjson.JSON;

import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;

/**
 * @author wukefan
 * @version 1.0.0
 * @date 2020/7/27 18:32
 */
public abstract class NoticeService<T> extends RadpService {
    @Override
    protected int bizInit(String s) {
        return 0;
    }

    @Override
    protected int bizProcess(String s, int i) {
        try {
            /* Step1：通道(交易)权限检查 */
            /* Step2：业务处理前实现接口 */
            rglog.info("---------------> 业务处理前处理 <---------------");
            T request = beforeBizProcess();
            /* Step3：业务逻辑处理 */
            rglog.info("---------------> 业务逻辑处理 <---------------");
            BizResponse response = callBizService(request);
            /* Step4：业务处理后实现接口 */
            rglog.info("---------------> 业务处理后处理 <---------------");
            afterBizProcess(response);
        } catch (Exception e) {
            XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
            String respCode;
            String respDesc;
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            e.printStackTrace(new PrintWriter(byteArrayOutputStream, true));
            rglog.error("业务异常信息:<{}>", byteArrayOutputStream.toString());
            if (e instanceof BizException) {
                respCode = ((BizException) e).getCode();
                respDesc = e.getMessage();
                rglog.error("业务处理失败，业务返回码:<{}>，业务返回信息:<{}>", respCode, respDesc);
            } else {
                rglog.error("系统处理失败，返回信息:<{}>", e);
                respCode = OltpRpcdEnum.OLTP_PROCESS_ERROR.getRespCode();
                respDesc = OltpRpcdEnum.OLTP_PROCESS_ERROR.getRespDesc();
            }
            try {
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_CODE, respCode);
                xmlTreeUtil.setXmlTreeStringValue(TreeNodeConstant.RESP_DESC, respDesc);
            } catch (Exception ex) {
                ex.printStackTrace(new PrintWriter(byteArrayOutputStream, true));
                rglog.error("设置节点值异常信息:<{}>", byteArrayOutputStream.toString());
                return -1;
            }

        }
        return 0;
    }

    @Override
    protected int bizTerminate(String s) {
        return 0;
    }

    /**
     * 业务调用前处理
     *
     * @return 业务处理请求结构
     */
    protected abstract T beforeBizProcess() throws Exception;

    /**
     * 业务处理服务调用
     *
     * @param request 业务处理信息
     * @return 业务处理应答结果
     */
    protected abstract BizResponse callBizService(T request) throws Exception;

    /**
     * 业务调用后处理
     *
     * @param response 业务响应结果
     */
    protected abstract void afterBizProcess(BizResponse response) throws Exception;


    /**
     * 通道、交易权限权限
     *
     * @throws Exception 业务处理异常
     */
    private void channelPermissionCheck() throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String instId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID);
        String msgSrcId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.SRC_SYS_ID);
        String txnNum = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.TXN_NUM);
        String bizType = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.BIZ_TYPE);
        if (instId.isEmpty() || msgSrcId.isEmpty() || txnNum.isEmpty() || bizType.isEmpty()) {
            rglog.error("instId:<{}> or channelId:<{}> or txnNum:<{}> or bizType:<{}> is null.", instId, msgSrcId, txnNum, bizType);
            throw new BizException(OltpRpcdEnum.PARAM_IS_EMPTY_OR_NULL);
        }
        String txnKey = instId.trim() + msgSrcId.trim() + txnNum.trim() + bizType.trim();
        TxnInfo txnInfo = JSON.parseObject(RedisUtil.onceGet(txnKey), TxnInfo.class);
        ChannelService channelService = new ChannelServiceImpl();
        if (null == txnInfo || null == txnInfo.getSrcTxnAuthCfg() || !channelService.channnelCheck(txnInfo)) {
            rglog.error("instId:<{}>,channel:<{}>,txnNum:<{}>,bizType:<{}> is not support.", instId, msgSrcId, txnNum, bizType);
            throw new BizException(OltpRpcdEnum.TRANS_NOT_SUPPORT);
        }
    }

}
